package com.lty.controller;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lty.common.BaseResponse;
import com.lty.common.DeleteRequest;
import com.lty.common.ErrorCode;
import com.lty.common.PageRequest;
import com.lty.common.ResultUtils;
import com.lty.exception.BusinessException;
import com.lty.model.dto.project.ProjectRequest;
import com.lty.model.entity.Project;
import com.lty.model.entity.ProjectTemplateRef;
import com.lty.model.entity.TemplateInfo;
import com.lty.model.enums.StatusEnum;
import com.lty.model.vo.ProjectVO;
import com.lty.model.vo.TemplateVO;
import com.lty.service.ProjectService;
import com.lty.service.ProjectTemplateRefService;
import com.lty.service.impl.TemplateService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lty
 */
@Slf4j
@RestController
@RequestMapping("/project")
public class ProjectController {

    @Resource
    private ProjectService projectService;

    @Resource
    private ProjectTemplateRefService projectTemplateRefService;

    @Resource
    public TemplateService templateService;

    @ApiOperation(value = "根据项目查询模板")
    @GetMapping(value = "/template/{id}")
    public BaseResponse<List<TemplateVO>> getTemplateByProjectId(@PathVariable Long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        List<ProjectTemplateRef> list = projectTemplateRefService.list(new LambdaQueryWrapper<>(new ProjectTemplateRef().setProjectId(id)));
        List<Long> templateIds = list.stream().map(e -> e.getTemplateId()).distinct().toList();
        List<TemplateInfo> templateInfoList = new ArrayList<>();
        if (templateIds.size() > 0) {
            templateInfoList = templateService.list(new LambdaQueryWrapper<TemplateInfo>()
                    .in(TemplateInfo::getId, templateIds).eq(TemplateInfo::getStatus, StatusEnum.ENABLE.getValue()));
        }
        List<TemplateVO> templateVOList = templateInfoList.stream().map(e -> {
            TemplateVO templateVO = new TemplateVO();
            BeanUtils.copyProperties(e, templateVO);
            return templateVO;
        }).collect(Collectors.toList());
        return ResultUtils.success(templateVOList);
    }


    @ApiOperation(value = "添加")
    @PostMapping("/add")
    public BaseResponse<Long> addProject(@RequestBody ProjectRequest projectAddRequest) {
        if (projectAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Project project = new Project();
        BeanUtils.copyProperties(projectAddRequest, project);
        boolean result = projectService.save(project);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "添加项目失败");
        }
        // 新增项目模板关系
        if (projectAddRequest.getTemplateIds() != null && projectAddRequest.getTemplateIds().size() > 0) {
            List<ProjectTemplateRef> newProjectTemplateRefList = new ArrayList<>();
            for (Long templateId : projectAddRequest.getTemplateIds()) {
                ProjectTemplateRef projectTemplateRef = new ProjectTemplateRef();
                projectTemplateRef.setProjectId(project.getId());
                projectTemplateRef.setTemplateId(templateId);
                newProjectTemplateRefList.add(projectTemplateRef);
            }
            projectTemplateRefService.saveBatch(newProjectTemplateRefList);
        }
        return ResultUtils.success(project.getId());
    }


    @ApiOperation(value = "修改")
    @PostMapping("/update")
    public BaseResponse<Boolean> updateProject(@RequestBody ProjectRequest projectUpdateRequest) {
        if (projectUpdateRequest == null || projectUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        Project project = new Project();
        BeanUtils.copyProperties(projectUpdateRequest, project);
        Project oldProject = projectService.getById(projectUpdateRequest.getId());
        if (oldProject == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        boolean result = projectService.updateById(project);
        // 修改项目模板关系
        List<Long> addTemplate = projectUpdateRequest.getAddTemplate();
        if (addTemplate != null && addTemplate.size() > 0) {
            List<ProjectTemplateRef> newProjectTemplateRefList = new ArrayList<>();
            for (Long templateId : addTemplate) {
                ProjectTemplateRef projectTemplateRef = new ProjectTemplateRef();
                projectTemplateRef.setProjectId(projectUpdateRequest.getId());
                projectTemplateRef.setTemplateId(templateId);
                newProjectTemplateRefList.add(projectTemplateRef);
            }
            projectTemplateRefService.saveBatch(newProjectTemplateRefList);
        }
        List<Long> deleteTemplate = projectUpdateRequest.getDeleteTemplate();
        if (deleteTemplate != null && deleteTemplate.size() > 0) {
            projectTemplateRefService.remove(new LambdaQueryWrapper<ProjectTemplateRef>().eq(ProjectTemplateRef::getProjectId, projectUpdateRequest.getId())
                    .in(ProjectTemplateRef::getTemplateId, deleteTemplate));
        }
        return ResultUtils.success(result);
    }

    @ApiOperation(value = "通过id获取")
    @GetMapping(value = "/get/{id}")
    public BaseResponse<ProjectVO> getByProjectId(@PathVariable Long id) {
        if (id <= 0) {
           throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        ProjectVO projectVO = new ProjectVO();
        Project project = projectService.getById(id);
        BeanUtils.copyProperties(project, projectVO);
        List<ProjectTemplateRef> list = projectTemplateRefService.list(new LambdaQueryWrapper<>(new ProjectTemplateRef().setProjectId(id)));
        projectVO.setTemplateIds(list.stream().map(ProjectTemplateRef::getTemplateId).collect(Collectors.toList()));
        return ResultUtils.success(projectVO);
    }

    @ApiOperation(value = "列表获取")
    @GetMapping(value = "/list")
    public BaseResponse<List<Project>> listProject(Project project) {
        project.setStatus(StatusEnum.ENABLE.getValue());
        Wrapper<Project> qw = this.buildQueryWrapper(project);
        List<Project> projectList = projectService.list(qw);
        return ResultUtils.success(projectList);
    }

    @ApiOperation(value = "分页获取")
    @GetMapping(value = "/list/page")
    public BaseResponse<Page<Project>> listProjectByPage(PageRequest pageRequest, Project project) {
        // 分页基本字段
        long current = pageRequest.getCurrent();
        long size = pageRequest.getPageSize();
        // 反爬虫
        if (size > 100) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "查询数量过多");
        }
        Page<Project> page = new Page<>(current,size);
        Page<Project> projectPage = projectService.page(page, this.buildQueryWrapper(project));
        return ResultUtils.success(projectPage);
    }

    @ApiOperation(value = "删除")
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteProject(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        Project oldProject = projectService.getById(id);
        if (oldProject == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        boolean b = projectService.removeById(id);
        return ResultUtils.success(b);
    }
    
    public Wrapper<Project> buildQueryWrapper(Project project) {
        LambdaQueryWrapper<Project> qw = new LambdaQueryWrapper<>();
        if(project != null) {
            if (project.getStatus() != null) {
                qw.eq(Project::getStatus, project.getStatus());
            }
        }
        qw.orderByAsc(Project::getSortable);
        return qw;
    }
}
